1 00:00:00,800 --> 00:00:01,460 Hey there. 2 00:00:01,460 --> 00:00:06,980 In this lecture we're going to be creating a combat knife melee weapon that all our players can use 3 00:00:06,980 --> 00:00:12,230 when they spawn into the game to go ahead and fight and kill any zombies that come their way. 4 00:00:15,460 --> 00:00:20,470 He gets started, what we're going to go ahead and do is open up our avatar tab and create a new rig 5 00:00:20,470 --> 00:00:25,180 using the rig builder, and we'll do a block avatar in our 15. 6 00:00:25,740 --> 00:00:31,080 And then we're going to head over to server storage, and we're going to grab our knife out of the tools 7 00:00:31,080 --> 00:00:31,800 folder. 8 00:00:31,800 --> 00:00:35,130 And we're going to change the parent equal to our rig right here. 9 00:00:35,610 --> 00:00:38,850 And then I believe it got parented to one of the body parts. 10 00:00:38,850 --> 00:00:41,310 So we'll move it as a child of our rig. 11 00:00:41,310 --> 00:00:42,030 There we go. 12 00:00:42,030 --> 00:00:46,800 And as you can see, the rig should now be holding the knife in the correct position. 13 00:00:48,240 --> 00:00:53,190 Now using this rig, we want to go ahead and create several animations for our knife. 14 00:00:53,190 --> 00:00:58,110 We want to create an animation for holding our knife, and we're going to want to create several animations 15 00:00:58,110 --> 00:01:00,630 for swinging our knife around. 16 00:01:01,150 --> 00:01:05,800 So we can go ahead and select our avatar, and then we'll open up our animation editor. 17 00:01:07,470 --> 00:01:09,690 Actually looks like we'll have to reselect our rig again. 18 00:01:09,720 --> 00:01:15,300 We can create a new animation clip, and this is where you're going to start animating for your knife. 19 00:01:15,330 --> 00:01:18,930 You'll want to have your animation be exactly one second in length. 20 00:01:18,930 --> 00:01:24,180 And that's because we're going to be adjusting how long this animation plays through our scripts. 21 00:01:24,180 --> 00:01:31,380 So by setting it at a one second duration, we are able to multiply that value by a percentage to determine 22 00:01:31,380 --> 00:01:34,350 how many seconds we would like this animation to last. 23 00:01:35,480 --> 00:01:40,730 So you can go ahead and start off by creating a starting pose for your knife. 24 00:01:40,970 --> 00:01:45,770 But once you have the starting pose for your knife down, what you want to make sure is that this button 25 00:01:45,770 --> 00:01:46,730 right here is checked. 26 00:01:46,730 --> 00:01:52,220 So we're looping the animation, and you also want to make sure you set the animation priority to movement. 27 00:01:52,220 --> 00:01:57,320 Once you've done that, you can go ahead and publish this animation to Roblox and give it a name of 28 00:01:57,320 --> 00:01:58,340 whatever you'd like. 29 00:01:58,340 --> 00:02:03,530 And then once you submit it and publish it to the game, there will be an ID that will pop up that you're 30 00:02:03,530 --> 00:02:04,820 going to copy. 31 00:02:04,820 --> 00:02:07,730 And we're going to be using these IDs for later. 32 00:02:07,730 --> 00:02:11,780 Now, I've already uploaded this animation, so I'm not going to re-upload it again, but we're going 33 00:02:11,780 --> 00:02:17,030 to move on and create the next series of our animations, which should be the swinging animations. 34 00:02:17,030 --> 00:02:23,600 And your swinging animations should start, and they should end with the same key frames that match 35 00:02:23,600 --> 00:02:24,980 your equip animation. 36 00:02:24,980 --> 00:02:28,910 So I can copy this and put this at the end of my track as well. 37 00:02:28,910 --> 00:02:33,770 So now we have the same holding position at the beginning and then the end of our animation. 38 00:02:33,770 --> 00:02:40,370 And then throughout all of these different points on our track is where we can go ahead and start animating 39 00:02:40,370 --> 00:02:45,410 the different swinging animations for when we click and use our knife. 40 00:02:47,230 --> 00:02:49,900 Okay, so I have made three attack animations. 41 00:02:49,900 --> 00:02:52,720 I've just called it attack one, attack two and attack three. 42 00:02:52,720 --> 00:02:58,990 So this is my first attack animation and then this is my second attack animation. 43 00:02:59,700 --> 00:03:02,550 And then this is my third attack animation. 44 00:03:02,550 --> 00:03:08,550 And you can see that all of my attack animations start and end with the same key frames as my equip 45 00:03:08,550 --> 00:03:09,300 animation. 46 00:03:09,300 --> 00:03:13,230 And then between those two frames is where I've animated the attack. 47 00:03:13,320 --> 00:03:17,550 I've also added a little bit of customization to these different key frames, such as. 48 00:03:17,550 --> 00:03:23,220 I've selected the easing style to be cubic, and I've changed the easing direction to be in and out. 49 00:03:23,220 --> 00:03:29,610 But of course you can go ahead and manipulate the easing style and the easing direction for your keyframes 50 00:03:29,610 --> 00:03:30,810 however you would like. 51 00:03:31,260 --> 00:03:36,390 Or if you would like to use these animations that I've created, then I'll have this rig attached to 52 00:03:36,390 --> 00:03:42,060 the lecture that you can go ahead and load these different animations and then publish them to Roblox. 53 00:03:42,060 --> 00:03:46,620 And then once you publish them and get all of those IDs, we can go ahead and start scripting. 54 00:03:47,600 --> 00:03:53,060 All right, so now what we could do is inside of our knife tool, we can go ahead and add a new module 55 00:03:53,060 --> 00:03:53,630 script. 56 00:03:53,630 --> 00:03:58,130 And this module script is just going to store a table of all the different properties we would like 57 00:03:58,130 --> 00:04:00,140 to have for our knife. 58 00:04:00,140 --> 00:04:03,320 I'll just rename this module script to properties. 59 00:04:05,640 --> 00:04:09,450 And then inside of my module, I can just go ahead and create a variable. 60 00:04:09,450 --> 00:04:12,270 I'll just call it self and it's going to be a table. 61 00:04:12,270 --> 00:04:15,990 And then we'll make sure to return self at the end of the module script. 62 00:04:15,990 --> 00:04:20,220 And inside of this table is where we will have all of the properties for our knife. 63 00:04:20,220 --> 00:04:23,220 For example we can create a key, we can call it damage. 64 00:04:23,220 --> 00:04:27,420 And this will be the base damage for how much we want to deal to zombies in our game. 65 00:04:27,420 --> 00:04:30,000 And we can set it to a value of like 95. 66 00:04:30,210 --> 00:04:35,640 And then if we would like to implement a system where every time a player swings and they hit a zombie, 67 00:04:35,640 --> 00:04:40,710 there is a chance for them to get a critical hit, then we can go ahead and create a key value pair. 68 00:04:40,710 --> 00:04:48,690 I'll call it critical hit chance and we can set it to a float to represent like the percentage chance 69 00:04:48,690 --> 00:04:50,430 that we'll have of getting a critical hit. 70 00:04:50,430 --> 00:04:52,020 And we could do like 0.15. 71 00:04:52,020 --> 00:04:54,330 So that would be like a 15% chance. 72 00:04:55,140 --> 00:05:03,630 And if we do get a critical hit chance, then what we can do is define a table that can store the minimum 73 00:05:03,630 --> 00:05:08,790 and the maximum value that we should multiply our damage by to give them a critical hit. 74 00:05:08,790 --> 00:05:12,360 So we could call this our critical hit multiplier. 75 00:05:12,930 --> 00:05:18,630 And inside of here we can have a minimum and a maximum key and set it equal to some kind of value. 76 00:05:18,630 --> 00:05:23,220 So the minimum we could do is 1.3 times the base damage. 77 00:05:23,220 --> 00:05:26,430 And then the max we could do like 1.9 times the base damage. 78 00:05:26,430 --> 00:05:32,250 So this gives them a little bit more opportunity to deal extra damage to zombies that are fighting with 79 00:05:32,250 --> 00:05:33,510 using their knife. 80 00:05:33,900 --> 00:05:39,930 And then another thing we want to define is a cooldown between each time the player swings their knife. 81 00:05:39,930 --> 00:05:42,960 So when the player swings their knife, the animation is going to play. 82 00:05:42,960 --> 00:05:48,510 And then we're going to wait until the animation is finished playing, and then we can apply some sort 83 00:05:48,510 --> 00:05:50,820 of cooldown before they can go ahead and swing again. 84 00:05:50,820 --> 00:05:57,240 Now, we don't want this swing cooldown to be too long, so we could set it to a value of like 0.1 seconds. 85 00:05:58,120 --> 00:06:02,410 Next we can have a section in our properties for animations. 86 00:06:02,770 --> 00:06:08,950 And inside of here is where we're going to want to use those IDs that we copied for our animations and 87 00:06:08,950 --> 00:06:10,510 store them in this module script. 88 00:06:10,510 --> 00:06:13,360 So we could have a property, I'll call it swing animations. 89 00:06:13,360 --> 00:06:18,790 And this will just be an array that stores all of the different IDs for the swinging animations. 90 00:06:19,330 --> 00:06:25,180 So I've just gone ahead and copied each of the IDs for my swinging animations for my attack one, two 91 00:06:25,180 --> 00:06:27,070 and three animations. 92 00:06:27,070 --> 00:06:28,900 You'll want to do the exact same thing. 93 00:06:28,900 --> 00:06:36,670 Copy those IDs and make sure you place this asset ID colon and then slash slash prefix before it. 94 00:06:36,670 --> 00:06:38,380 And then you can put your ID here. 95 00:06:38,380 --> 00:06:41,740 And these are my three attack or swinging animations. 96 00:06:41,860 --> 00:06:46,240 And then I'll go ahead and define a key for my equip animation. 97 00:06:46,240 --> 00:06:48,550 So I'll call this my equip animation. 98 00:06:48,550 --> 00:06:53,440 And again here's where you're going to want to paste the ID for your equip animation. 99 00:06:53,950 --> 00:06:55,810 So I'll paste mine in right here. 100 00:06:56,260 --> 00:06:59,050 And then let me make sure to put a comma afterwards. 101 00:06:59,050 --> 00:07:01,450 So that way we're not getting that error. 102 00:07:02,710 --> 00:07:07,870 And then the last thing we want to define for our animations is specifically how long we want our swing 103 00:07:07,870 --> 00:07:12,760 animations to last, because if you remember, each one of our animations lasts for one second. 104 00:07:12,760 --> 00:07:19,180 However, it looks kind of slow when you have to swing over the entire duration of one second in our 105 00:07:19,180 --> 00:07:19,990 animation. 106 00:07:19,990 --> 00:07:25,240 So here is where we can define the animation duration for our swing animations. 107 00:07:25,240 --> 00:07:28,630 And we could do something like 0.35 seconds. 108 00:07:29,900 --> 00:07:34,220 The next thing we can go ahead and define are some sounds for our knife. 109 00:07:34,220 --> 00:07:38,600 So we want to have a swing sound and this will be the swing sound ID. 110 00:07:39,800 --> 00:07:43,220 And then we can also define the hit sound ID. 111 00:07:44,740 --> 00:07:47,800 And this is where we can go ahead and open up our toolbox. 112 00:07:47,800 --> 00:07:56,110 And we can go to the audio section and try to find any good audio sounds for swinging and hitting something 113 00:07:56,110 --> 00:07:57,370 with our knife. 114 00:07:58,520 --> 00:08:02,570 So I found two good audios to use for swinging and hitting. 115 00:08:02,570 --> 00:08:08,510 If you would like to use the exact same audios as me, you can go ahead and copy these IDs and paste 116 00:08:08,510 --> 00:08:14,390 them inside of your module script, because these are universal sounds that can be used across any game. 117 00:08:15,110 --> 00:08:20,900 Now, another thing I want to go ahead and do is I want to manipulate the sounds so they don't sound 118 00:08:20,900 --> 00:08:23,570 the exact same every time we're swinging our tool. 119 00:08:23,570 --> 00:08:31,010 Instead, we want to be able to pitch the sound up or down randomly by using a pitch shift instance. 120 00:08:31,100 --> 00:08:36,110 And to show an example of this, I'm just going to create a new sound instance inside of my knife. 121 00:08:36,880 --> 00:08:41,020 And then I'll add and then I'll copy one of these sound IDs. 122 00:08:41,020 --> 00:08:42,670 For example, we could do the swing sound. 123 00:08:42,670 --> 00:08:43,780 I'll copy this. 124 00:08:43,780 --> 00:08:46,750 And then I can place it inside of the sound ID property. 125 00:08:46,750 --> 00:08:49,630 So then you can go ahead and listen to what the swing sound is. 126 00:08:49,870 --> 00:08:51,220 That's our swing sound. 127 00:08:51,430 --> 00:08:58,030 And then I want to be able to add a pitch shift sound effect, which is going to shift the octave of 128 00:08:58,030 --> 00:08:59,890 the sound by default. 129 00:08:59,890 --> 00:09:05,890 If we set it to one, that means our sound is going to sound the exact same. 130 00:09:05,890 --> 00:09:10,030 But I can go ahead and pitch the sound up or down using this octave property. 131 00:09:10,030 --> 00:09:14,410 For example, if I want the sound to have a lower pitch, I could do something like 0.8. 132 00:09:14,410 --> 00:09:20,020 And now if you listen, it has a different sound, and then I can also pitch it up higher to like 1.2. 133 00:09:21,410 --> 00:09:22,070 And there you go. 134 00:09:22,070 --> 00:09:23,180 It sounds different again. 135 00:09:23,180 --> 00:09:29,180 So we want to basically pitch or change the pitch of our sound each time we swing our knife. 136 00:09:29,180 --> 00:09:32,090 So it's not the exact same sound playing over and over again. 137 00:09:32,090 --> 00:09:34,130 And we want to do that for both of our sounds. 138 00:09:34,130 --> 00:09:41,510 So I'll create a property, I'll call it pitch shift octaves to define a minimum and a maximum value 139 00:09:41,510 --> 00:09:43,640 for the pitch. 140 00:09:44,120 --> 00:09:46,850 So the minimum we could do like 0.8. 141 00:09:46,850 --> 00:09:49,430 And then for the max we could do 1.2. 142 00:09:50,940 --> 00:09:57,720 And then I want to go ahead and define the properties that all of the sounds are going to be using. 143 00:09:57,810 --> 00:10:02,040 So for example, we want to fill this up with different sound properties. 144 00:10:02,040 --> 00:10:07,320 So for example, if we look in the sound we want to go ahead and change the roll off max distance and 145 00:10:07,320 --> 00:10:13,350 the roll off minimum distance as well as the roll off mode and the volume as well. 146 00:10:13,350 --> 00:10:18,690 So inside of here we can go ahead and define like roll off max distance. 147 00:10:18,690 --> 00:10:21,630 And we could do a distance of up to 40 studs away. 148 00:10:21,630 --> 00:10:27,690 So anybody further than 40 studs away is not going to hear our knife swing or hit anything. 149 00:10:27,690 --> 00:10:31,440 And then we'll do roll off min distance. 150 00:10:31,440 --> 00:10:33,450 We'll set it to something like 15 studs. 151 00:10:33,450 --> 00:10:38,580 The roll off mode we want to set to the enum dot roll off mode dot. 152 00:10:38,880 --> 00:10:42,720 We could do inverse tapered which sounds the best in my opinion. 153 00:10:43,110 --> 00:10:47,160 And then the volume we can go ahead and set to something like 0.25. 154 00:10:47,160 --> 00:10:52,170 And that's going to be the properties or the sound properties for these two sound IDs. 155 00:10:53,070 --> 00:10:58,950 Now that we have all of the properties set up for our knife, we're going to go ahead and create a new 156 00:10:58,950 --> 00:11:03,870 local script as well as a new server script inside of our knife. 157 00:11:04,020 --> 00:11:08,250 I'll rename the local script to our knife listener. 158 00:11:10,630 --> 00:11:14,110 And I'll rename the server script to our knife handler. 159 00:11:16,160 --> 00:11:17,210 Inside of the local script. 160 00:11:17,210 --> 00:11:21,020 We're going to be using that exact same common template that we've been using before. 161 00:11:22,800 --> 00:11:26,910 And inside of our local script, we can go ahead and create a variable called tool to reference the 162 00:11:26,910 --> 00:11:29,190 tool itself, which is simply script dot parent. 163 00:11:30,030 --> 00:11:35,670 And since this is a local script, we can also grab the player as well, so we'll get the player service. 164 00:11:36,850 --> 00:11:44,110 And then we can grab the player from players, local player, and then down inside of our handler section, 165 00:11:44,110 --> 00:11:49,510 we want to go ahead and listen to when our tool is equipped, when it's unequipped and when it's activated. 166 00:11:49,510 --> 00:11:56,800 So when our tool is equipped, this is where we would want to go ahead and play that equip animation. 167 00:11:56,800 --> 00:12:00,880 When our tool is unequipped, we want to stop playing that equip animation. 168 00:12:00,880 --> 00:12:07,360 And then when our tool is activated, we want to go ahead and tell the server that we've swung our knife, 169 00:12:07,360 --> 00:12:12,610 and that will let the server check if we hit anything and then damage that thing if we hit it. 170 00:12:13,310 --> 00:12:19,040 So in order to play the animations on our player's character, we're going to have to load them using 171 00:12:19,040 --> 00:12:23,390 the animator instance that is a child of the humanoid of our character. 172 00:12:23,390 --> 00:12:25,730 So we need to grab our player's character. 173 00:12:25,730 --> 00:12:30,710 We'll create a variable called character, and it's going to be equal to our player. 174 00:12:31,970 --> 00:12:34,190 And then we'll get their character. 175 00:12:34,190 --> 00:12:39,380 And just in case their character hasn't loaded or been replicated yet, then we're going to put an Or 176 00:12:39,380 --> 00:12:44,540 statement here, and we're going to wait for the character added event to fire, which will return our 177 00:12:44,540 --> 00:12:45,140 character. 178 00:12:45,140 --> 00:12:49,280 And then once we get our character, we can go ahead and grab our humanoid, which is a child of our 179 00:12:49,280 --> 00:12:52,430 character, and we're going to use wait for child humanoid. 180 00:12:52,820 --> 00:12:57,020 And then we can also grab the animator as well, which is inside of our humanoid. 181 00:12:57,020 --> 00:12:59,960 So we'll do humanoid wait for child animator. 182 00:13:00,730 --> 00:13:05,800 Now, in order for our local script to communicate with our server script, we'll need to create a remote 183 00:13:05,800 --> 00:13:06,130 event. 184 00:13:06,130 --> 00:13:08,770 So inside of our knife, we can create a new remote event. 185 00:13:08,770 --> 00:13:12,490 And I'm just going to call this my swung. 186 00:13:12,520 --> 00:13:14,110 This is my swung event. 187 00:13:14,920 --> 00:13:19,930 So whenever I click or activate the tool and I swing my knife, I can fire this event to the server 188 00:13:19,930 --> 00:13:22,930 to let the server know, hey, I've activated my tool! 189 00:13:23,740 --> 00:13:25,840 So we'll make a reference to our swung event. 190 00:13:27,490 --> 00:13:30,280 A sequel to tool Dot swung. 191 00:13:30,790 --> 00:13:37,600 And then we'll also get the properties for our tool as well, and we'll require from our tool and we'll 192 00:13:37,600 --> 00:13:39,430 get properties. 193 00:13:40,960 --> 00:13:46,540 Last but not least, we're also going to need a random data type to randomly pick which swing animation 194 00:13:46,540 --> 00:13:48,700 we want to play when we activate our tool. 195 00:13:48,700 --> 00:13:50,650 So I'll just call this variable RNG. 196 00:13:50,650 --> 00:13:53,800 And that's going to be equal to a new random data type. 197 00:13:54,280 --> 00:14:01,720 Now what we can go ahead and do is create a new private function for loading animation instances on 198 00:14:01,720 --> 00:14:03,070 our players character. 199 00:14:03,070 --> 00:14:06,790 So I'm going to call this function create track. 200 00:14:08,190 --> 00:14:13,170 And we're going to get past an animation ID to this function. 201 00:14:13,530 --> 00:14:17,490 And what I want this function to do is I want it to create a new animation instance. 202 00:14:17,490 --> 00:14:19,380 So I'll have a variable called animation. 203 00:14:19,380 --> 00:14:22,590 And that's going to be equal to instance dot new animation. 204 00:14:26,940 --> 00:14:33,210 And then we want to go ahead and set the animations animation ID equal to the animation id passed to 205 00:14:33,210 --> 00:14:34,230 this function. 206 00:14:34,590 --> 00:14:41,340 And then from that point inside of the animator, we can use the load animation function and pass our 207 00:14:41,340 --> 00:14:42,480 animation instance. 208 00:14:42,480 --> 00:14:45,390 And that's going to return to us that track. 209 00:14:45,480 --> 00:14:48,150 So we'll return it at the end of this function. 210 00:14:48,910 --> 00:14:53,170 And that way we can go ahead and create a variable. 211 00:14:53,170 --> 00:14:55,390 I'm going to call this my equip track. 212 00:14:55,390 --> 00:14:56,800 And that's going to be equal to. 213 00:14:56,800 --> 00:14:58,990 And we're going to use our create track function. 214 00:14:59,620 --> 00:15:02,890 And inside of our properties we have our equip animation. 215 00:15:02,890 --> 00:15:06,040 So we're going to load the equip animation on our player's character. 216 00:15:06,040 --> 00:15:10,900 And that way when we equip our tool we can play this equip track. 217 00:15:11,290 --> 00:15:17,140 And then when we unequip the tool we can stop playing this animation track. 218 00:15:17,560 --> 00:15:23,800 Now when we go ahead and swing our tool, what we want to do is we want to play a random swinging animation. 219 00:15:23,800 --> 00:15:25,930 So we'll get a swing track. 220 00:15:27,650 --> 00:15:33,680 From our Create Track function, and the animation ID we want to pass is going to be a random one. 221 00:15:33,680 --> 00:15:38,450 So inside of our properties we can get that swing animations table. 222 00:15:38,450 --> 00:15:43,460 And then we're going to index it with a random number to grab a random animation. 223 00:15:43,460 --> 00:15:46,910 So we're going to do RNG next integer one. 224 00:15:46,910 --> 00:15:53,150 And then we're going to get the total amount of elements inside of our swing animations table. 225 00:15:53,150 --> 00:15:55,610 So this will be from 1 to 3. 226 00:15:55,610 --> 00:15:59,270 We'll get that random swing track and then we can play it. 227 00:16:01,820 --> 00:16:09,470 And at the same time, we also may want to actually adjust the speed of our animation track. 228 00:16:10,320 --> 00:16:16,950 Unfortunately, it's not auto filling these functions because it doesn't know what a swing track is. 229 00:16:17,370 --> 00:16:23,010 So just in case, what I'm going to do is a little bit more type annotation, and I'm going to denote 230 00:16:23,010 --> 00:16:27,480 that this function returns an animation track. 231 00:16:27,780 --> 00:16:31,410 Again you do not need to worry about type annotation. 232 00:16:31,410 --> 00:16:33,600 And this is not required for this function. 233 00:16:33,600 --> 00:16:38,430 But just for the sake of this lecture to make it easier to follow along, I'm going to. 234 00:16:39,080 --> 00:16:40,100 Type, annotate it. 235 00:16:40,100 --> 00:16:47,570 That way we can get the auto fill and it tells us exactly what this animation track can do. 236 00:16:47,570 --> 00:16:51,560 So for example, here we want to adjust the speed of the animation track. 237 00:16:52,130 --> 00:16:57,110 And it says a positive value for speed plays the animation forward and negative one plays it backward 238 00:16:57,110 --> 00:16:58,370 and zero pauses it. 239 00:16:59,150 --> 00:17:05,210 So the speed we want to set it to is going to be equal to the value of one, which is the length of 240 00:17:05,210 --> 00:17:05,870 our animation. 241 00:17:05,870 --> 00:17:10,280 And we want to divide this value by our properties dot animation duration. 242 00:17:10,760 --> 00:17:18,290 And that way we're setting the speed of our swing track to the correct speed to play it for the duration 243 00:17:18,290 --> 00:17:20,120 defined in this property. 244 00:17:20,120 --> 00:17:25,790 Then we can play the swing track, and then we're going to refer to our swing event, and we're going 245 00:17:25,790 --> 00:17:30,230 to fire to the server that, hey, we have swung our tool. 246 00:17:31,530 --> 00:17:35,040 And then we're going to wait for our swing track to stop playing. 247 00:17:35,040 --> 00:17:36,750 So we'll wait for this event. 248 00:17:37,290 --> 00:17:42,240 And once it's done playing, we can go ahead and destroy this swing track. 249 00:17:42,240 --> 00:17:44,970 So that way we clean it up off of the character. 250 00:17:45,580 --> 00:17:53,470 And then after the swing track is over, this is where we would want to wait for our swing cooldown. 251 00:17:53,470 --> 00:17:58,780 So we could put a yield statement here and wait for the properties dot swing cooldown. 252 00:17:59,430 --> 00:18:05,460 And that means to prevent the player from rapidly firing this event and executing this code multiple 253 00:18:05,460 --> 00:18:08,160 times, we're going to need to create a Debounce variable. 254 00:18:08,190 --> 00:18:10,380 So up here I'll create a variable. 255 00:18:10,380 --> 00:18:13,950 I'll just call it swing Debounce set it to false by default. 256 00:18:13,950 --> 00:18:16,290 But then when we activate our tool. 257 00:18:17,050 --> 00:18:19,900 We'll set swing de bounce equal to true. 258 00:18:20,050 --> 00:18:23,680 And before we do that, we're going to check if swing de bounce is already true. 259 00:18:23,680 --> 00:18:25,600 And if it is, we're going to return. 260 00:18:25,630 --> 00:18:27,280 Then we'll set it to true. 261 00:18:27,310 --> 00:18:32,830 We'll wait for our cool down and then we'll set swing de bounce back to false. 262 00:18:33,590 --> 00:18:38,870 Alrighty, we should now have all of the client stuff set up for our knife. 263 00:18:38,870 --> 00:18:43,070 So when we activate our knife, we should play a random swinging animation. 264 00:18:43,070 --> 00:18:48,140 And then when we equip and unequip it, the equip track should play and then stop playing. 265 00:18:48,140 --> 00:18:52,520 So we'll go ahead and move our knife into the starter pack. 266 00:18:52,520 --> 00:18:56,240 So that way our player can use it and then we'll play our game. 267 00:18:57,470 --> 00:19:02,750 And then we'll click our play button and we'll spawn into our game, and we can go ahead and pull out 268 00:19:02,750 --> 00:19:03,680 our knife. 269 00:19:03,830 --> 00:19:04,520 There we are. 270 00:19:04,520 --> 00:19:05,990 Our equip animation is playing. 271 00:19:05,990 --> 00:19:07,130 And then if I click. 272 00:19:08,350 --> 00:19:09,100 There you go. 273 00:19:09,100 --> 00:19:16,390 As you can see, it is swinging our knife, but it appears that the animation is still slow. 274 00:19:17,260 --> 00:19:24,580 So we may have to actually adjust the speed of our swing track after we start playing it. 275 00:19:24,580 --> 00:19:26,170 So let's go ahead and try that instead. 276 00:19:26,200 --> 00:19:31,960 I believe that our animation track actually has to be playing first before we are able to adjust the 277 00:19:31,960 --> 00:19:32,560 speed. 278 00:19:33,130 --> 00:19:34,780 So let's go ahead and try this again. 279 00:19:36,280 --> 00:19:38,110 So if we spawn into our map. 280 00:19:38,680 --> 00:19:40,060 And we get our knife right here. 281 00:19:40,060 --> 00:19:42,910 If we click, there we go. 282 00:19:42,910 --> 00:19:48,610 Now the speed of our swinging animations has been properly adjusted. 283 00:19:49,440 --> 00:19:55,890 So now the next thing we need to do is implement the sounds for our knife, as well as listen for when 284 00:19:55,890 --> 00:20:01,230 any humanoid in our game gets hit by our knife, and then we can damage them accordingly. 285 00:20:01,930 --> 00:20:06,490 So if I put my knife back inside of my rig. 286 00:20:07,330 --> 00:20:10,930 There is an invisible part inside of my knife called touch. 287 00:20:10,930 --> 00:20:12,700 So let me make it opaque. 288 00:20:12,940 --> 00:20:17,920 And this is the part where we're going to be listening for when anything touches this part, such as 289 00:20:17,920 --> 00:20:18,520 a limb. 290 00:20:18,520 --> 00:20:20,290 Then we're going to check what part. 291 00:20:20,320 --> 00:20:25,540 Touch this part, and if that part belonged to a humanoid, and if it did, and that humanoid is not 292 00:20:25,540 --> 00:20:27,880 another player, we're going to go ahead and damage them. 293 00:20:27,880 --> 00:20:34,810 Now, of course, you can adjust the length of this part to be longer, to change or increase the range 294 00:20:34,810 --> 00:20:40,000 of our knife when we swing it, but I'm going to leave it at this distance for now, because I think 295 00:20:40,000 --> 00:20:42,220 that should be good enough for our knife. 296 00:20:43,160 --> 00:20:50,720 So inside of our Nifs server scripts, we're going to go ahead and make the same reference to that event. 297 00:20:50,780 --> 00:20:54,800 So I'll create a variable, I'll call it swung Event. 298 00:20:54,800 --> 00:21:00,110 And before we can get the swing event we need to create a variable for our tool which is just script 299 00:21:00,110 --> 00:21:00,950 dot parent. 300 00:21:00,980 --> 00:21:04,310 Then we can refer to our tool and get the swung event. 301 00:21:05,500 --> 00:21:09,100 And then we also want to make a reference to, for example, the touch part in our tool. 302 00:21:09,100 --> 00:21:10,780 So tool dot touch. 303 00:21:12,000 --> 00:21:15,090 And then we also want to grab the properties for our tool as well. 304 00:21:15,090 --> 00:21:18,930 So we can require tool dot properties. 305 00:21:19,530 --> 00:21:23,460 And then from this point we can go ahead and listen to our swung event. 306 00:21:24,570 --> 00:21:26,100 Dot on server event. 307 00:21:26,100 --> 00:21:30,000 Connect a function and we'll get the player that fired this event. 308 00:21:30,570 --> 00:21:35,640 And something very important that we need to do is we need to make sure that whoever fired this event 309 00:21:35,640 --> 00:21:39,000 is actually the player that has this tool equipped. 310 00:21:39,000 --> 00:21:44,610 And the way we can do that is we can check if this player's name that fired this event, if it is not 311 00:21:44,610 --> 00:21:50,310 equal to the tool's parent dot name, then we're going to return. 312 00:21:50,310 --> 00:21:56,130 So the parent of this tool, when it is activated should be the player's character and the name of our 313 00:21:56,130 --> 00:21:59,700 player's character and the name of the player instance should be the same. 314 00:21:59,700 --> 00:22:05,520 Now, if an exploiter fired this event for another player, obviously the names are not going to match 315 00:22:05,520 --> 00:22:11,850 up, so we're just going to ignore whoever fired this event because they're not the owner or the person 316 00:22:11,850 --> 00:22:13,380 who has the tool equipped. 317 00:22:13,860 --> 00:22:14,640 Otherwise. 318 00:22:14,640 --> 00:22:19,620 Another important thing we need to do is we need to make sure we implement that same debounce that we 319 00:22:19,620 --> 00:22:26,760 had on the client on the server as well, because any exploiter could easily bypass this client side 320 00:22:26,760 --> 00:22:31,680 debounce and basically swing their knife super, super fast, which we don't want. 321 00:22:31,680 --> 00:22:33,480 So we'll create a variable. 322 00:22:34,350 --> 00:22:37,230 And I'm just going to call this variable swinging. 323 00:22:37,230 --> 00:22:39,540 And it's just going to store a boolean. 324 00:22:39,540 --> 00:22:40,770 We'll set it to false. 325 00:22:41,160 --> 00:22:44,790 And then we're just going to do the exact same thing that we did in our local script. 326 00:22:44,790 --> 00:22:47,700 If we are already swinging the knife we're going to return. 327 00:22:47,700 --> 00:22:50,340 Otherwise we can set swinging equal to true. 328 00:22:51,750 --> 00:22:55,950 And we'll actually do this after the first if statement. 329 00:22:56,560 --> 00:23:02,200 And inside of here is where we will put all our code, and after that we'll set swinging back to false. 330 00:23:03,890 --> 00:23:08,840 So what we want to do here is we want to go ahead and play the swinging sound, and then we want to 331 00:23:08,840 --> 00:23:10,460 go ahead and check if we touched anything. 332 00:23:10,460 --> 00:23:17,300 And if we did, we're going to damage that thing we touched and play the stabbing sound so we can go 333 00:23:17,300 --> 00:23:20,870 ahead and create a function for creating a sound instance. 334 00:23:20,870 --> 00:23:22,340 We'll call it create sound. 335 00:23:22,340 --> 00:23:29,750 And here we can get past the parent for the sound instance as well as, um, the table of those sound 336 00:23:29,750 --> 00:23:34,220 properties and the ID of the sound instance as well. 337 00:23:34,220 --> 00:23:36,080 Then we can create a new sound instance. 338 00:23:36,080 --> 00:23:37,820 So instance dot new sound. 339 00:23:39,130 --> 00:23:44,080 And then with all these properties on the table, we can loop through, grab every property and their 340 00:23:44,080 --> 00:23:46,780 value inside of our sound properties. 341 00:23:47,480 --> 00:23:53,780 And then we can go ahead and update that property on our sound instance with the respective value. 342 00:23:53,780 --> 00:23:59,360 So if you remember in our properties module script, we have a sound properties table with the name 343 00:23:59,360 --> 00:24:04,400 of the property and the value we would like to update that property to. 344 00:24:05,060 --> 00:24:11,210 Once we do that, we can go ahead and set the sound ID equal to the id passed to this function. 345 00:24:12,380 --> 00:24:16,880 And now we can set the parent of the sound equal to the parent passed to the function, and then we'll 346 00:24:16,880 --> 00:24:19,070 just return the sound instance. 347 00:24:20,420 --> 00:24:24,710 We also want to create a function for creating that pitch shift. 348 00:24:24,710 --> 00:24:27,890 So we'll call this function create pitch shift. 349 00:24:28,040 --> 00:24:32,480 We'll get passed the parent that this pitch shift should belong to. 350 00:24:32,480 --> 00:24:36,500 And then the value we should set for that octave property. 351 00:24:36,500 --> 00:24:39,020 So we'll create a new pitch shift. 352 00:24:39,020 --> 00:24:42,620 So instance dot new pitch shift sound effect. 353 00:24:43,070 --> 00:24:47,960 And then inside of that we can go ahead and update the octave to be equal to that value. 354 00:24:49,590 --> 00:24:54,150 We'll set the parent equal to the parent passed to the function, and then we can return this pitch 355 00:24:54,150 --> 00:24:54,810 shift. 356 00:24:55,620 --> 00:24:58,290 So now what we can do is we can go ahead and create a variable. 357 00:24:58,290 --> 00:24:59,550 I'll call it swing sound. 358 00:24:59,550 --> 00:25:02,010 And that's going to be equal to create sound. 359 00:25:02,010 --> 00:25:05,100 The parent of the sound is going to be the handle of our tool. 360 00:25:05,100 --> 00:25:06,810 So we can do tool dot handle. 361 00:25:07,110 --> 00:25:10,620 The sound properties is going to be inside of our module script. 362 00:25:10,620 --> 00:25:12,060 So sound properties. 363 00:25:13,200 --> 00:25:19,080 And then the ID is going to be our properties dot swing sound ID. 364 00:25:20,930 --> 00:25:25,010 Then we can go ahead and create the pitch shift for the sound as well. 365 00:25:25,010 --> 00:25:29,660 So the parent is going to be our swing sound and the value is going to be a random value. 366 00:25:29,660 --> 00:25:31,850 So we're going to need a random number generator. 367 00:25:31,850 --> 00:25:36,500 So I'll create another RNG variable which is a new random data type. 368 00:25:36,500 --> 00:25:43,730 And then we can do RNG next number because we are going to be picking a random decimal number. 369 00:25:44,150 --> 00:25:50,150 And the minimum value is going to be our properties dot pitch shift octave dot minimum. 370 00:25:50,360 --> 00:25:54,590 And then the maximum is going to be properties dot pitch shift octaves dot max. 371 00:25:56,900 --> 00:26:00,110 Then we can go ahead and play this swing sound. 372 00:26:00,760 --> 00:26:03,850 And then when this swing sound is finished playing. 373 00:26:03,850 --> 00:26:09,220 So we'll listen to the end of the event, we'll connect a function, and then we're going to basically 374 00:26:09,220 --> 00:26:12,340 destroy this swing sound because we don't need it anymore. 375 00:26:12,340 --> 00:26:16,540 And we want to go ahead and clean up any instances that were no longer using. 376 00:26:17,440 --> 00:26:18,040 Otherwise. 377 00:26:18,040 --> 00:26:22,660 Once we're doing that, we want to go ahead and create a yield statement here and we're going to wait 378 00:26:22,660 --> 00:26:25,540 for the properties dot swing cooldown. 379 00:26:26,050 --> 00:26:31,780 And then we also want to wait for the duration of our animation or our swing animation. 380 00:26:31,780 --> 00:26:34,300 So that's properties dot animation duration. 381 00:26:35,680 --> 00:26:41,530 So now any time we swing and we fire this event, we're forcing a cooldown and the player is not going 382 00:26:41,530 --> 00:26:45,640 to be able to execute this code again until this yield statement is up. 383 00:26:45,640 --> 00:26:47,680 And then we set swinging back to false. 384 00:26:47,680 --> 00:26:50,500 So let's go ahead and test what we have done so far. 385 00:26:50,500 --> 00:26:53,740 We can move our knife back into. 386 00:26:55,120 --> 00:26:56,230 The starter pack. 387 00:26:57,370 --> 00:27:02,680 And we'll playtest our game and let's see if we get a swinging sound when we activate our knife. 388 00:27:02,680 --> 00:27:05,650 So if I hold it and then click, there we go. 389 00:27:05,830 --> 00:27:10,060 As you can see, we're now playing a swinging sound anytime we activate our knife. 390 00:27:10,060 --> 00:27:10,840 Very cool. 391 00:27:12,750 --> 00:27:17,580 Now, what we need to go ahead and do is detect when that part touches something, and then we can go 392 00:27:17,580 --> 00:27:19,050 ahead and damage it. 393 00:27:20,160 --> 00:27:28,020 So back inside of our server script, when we activate and we fire this event, what we can go ahead 394 00:27:28,020 --> 00:27:31,770 and do is listen for when our touch part gets touched. 395 00:27:31,770 --> 00:27:38,700 And we'll connect a function to this and get that part that touched the touch part in our tool. 396 00:27:39,420 --> 00:27:42,270 And let's go ahead and create a dedicated function for this. 397 00:27:43,310 --> 00:27:48,710 I'm going to call this function on touched, and we'll get past that part that touched us. 398 00:27:48,710 --> 00:27:52,130 And then we also want to go ahead and grab the player. 399 00:27:53,340 --> 00:27:59,940 As well, because when we damage a zombie, we want to go ahead and be able to keep track of whoever 400 00:27:59,940 --> 00:28:01,740 last damaged a zombie. 401 00:28:01,830 --> 00:28:06,660 And if we go to the zombie folder inside of server storage and we take a look at one of our zombies, 402 00:28:06,660 --> 00:28:11,760 there is an object value inside each of our zombies called Who Last Damage. 403 00:28:11,940 --> 00:28:19,200 And we're going to update the value in here equal to the player or whoever last damaged the zombie. 404 00:28:19,230 --> 00:28:25,740 That way, when the zombie dies in the future, we can keep track of who killed what zombie and then 405 00:28:25,740 --> 00:28:29,220 update like a kills value in the player's leaderboard. 406 00:28:29,890 --> 00:28:33,850 So it's important that we get whoever attacked this zombie. 407 00:28:33,850 --> 00:28:37,210 That way we can update the object values inside of them. 408 00:28:38,260 --> 00:28:43,210 So when this function gets executed, we first want to make sure that we are swinging our knife. 409 00:28:43,210 --> 00:28:46,930 So if we're not swinging the knife just in case, we're going to return. 410 00:28:48,560 --> 00:28:53,780 Otherwise, we can go ahead and grab the humanoid, which is going to be equal to the other part dot 411 00:28:53,780 --> 00:28:54,590 parent. 412 00:28:54,590 --> 00:28:58,670 And we're going to find First Child, which is a humanoid. 413 00:28:58,670 --> 00:29:06,260 So we want to make sure that the part we touched belongs to a character model or a humanoid model. 414 00:29:07,140 --> 00:29:10,050 If there is not a humanoid, then we're just going to return. 415 00:29:10,770 --> 00:29:15,510 Otherwise, we want to make sure that this humanoid does not belong to another player in our game. 416 00:29:15,720 --> 00:29:18,900 So that means we're going to have to grab the player service. 417 00:29:25,130 --> 00:29:31,730 And then what we could do is we want to use the players, get player from character function and pass 418 00:29:32,150 --> 00:29:33,920 um, other part dot parent. 419 00:29:34,430 --> 00:29:39,770 And if this function does return a player then we're just going to return. 420 00:29:41,050 --> 00:29:46,540 Otherwise, what we can go ahead and do is since we've confirmed that we've hit a character model and 421 00:29:46,540 --> 00:29:48,250 it's not a player, we can damage them. 422 00:29:48,700 --> 00:29:50,860 And we also want to play that stabbing sound. 423 00:29:50,860 --> 00:29:54,460 So I'm just going to copy what we did down here, paste that up here. 424 00:29:54,460 --> 00:30:00,820 And instead I'm going to rename this using Control Shift and are going to rename this as my hit sound. 425 00:30:01,780 --> 00:30:04,720 And instead we're going to pass the. 426 00:30:05,750 --> 00:30:07,280 Hit sound ID. 427 00:30:09,240 --> 00:30:10,800 Then we'll play the hit sound. 428 00:30:10,800 --> 00:30:16,440 And afterwards, well, we can go ahead and do is calculate a critical chance. 429 00:30:16,440 --> 00:30:19,410 So remember in our properties module script we have. 430 00:30:20,310 --> 00:30:22,350 A critical hit chance. 431 00:30:23,040 --> 00:30:25,950 So I can do is I'm going to create a variable called damage. 432 00:30:25,950 --> 00:30:28,560 And it's going to be equal to my properties dot damage. 433 00:30:29,410 --> 00:30:37,240 And then if by using our RNG data type and we use the next number function. 434 00:30:37,830 --> 00:30:40,350 And the value is going to be between 0 and 1. 435 00:30:40,680 --> 00:30:46,500 If the value returned by this function is less than or equal to our properties. 436 00:30:46,500 --> 00:30:49,680 Dot chance or critical hit chance. 437 00:30:50,710 --> 00:30:58,270 Then we can go ahead and update this damage value and multiply it by one of the, um, critical hit 438 00:30:58,270 --> 00:30:59,920 multiplier values. 439 00:31:00,620 --> 00:31:05,840 So since our critical hit chance is 0.15, that's a 15% chance. 440 00:31:05,840 --> 00:31:13,100 So if any of the decimal numbers generated by this function is less than or equal to 0.15, then we 441 00:31:13,100 --> 00:31:16,730 can go ahead and set damage. 442 00:31:17,030 --> 00:31:22,550 And we're going to multiply this value by and we're going to use RNG. 443 00:31:22,580 --> 00:31:23,780 Next number. 444 00:31:24,260 --> 00:31:29,030 The minimum value is going to be properties dot critical hit multiplier dot min. 445 00:31:29,030 --> 00:31:32,750 And then properties dot critical hit multiplier dot max. 446 00:31:33,810 --> 00:31:38,460 So we've just updated the damage to reflect a new critical hit. 447 00:31:39,450 --> 00:31:45,360 And afterwards we can get that humanoid that we grabbed up here. 448 00:31:45,360 --> 00:31:51,180 And then there's a function called take damage for humanoids, and we can go ahead and pass the damage 449 00:31:51,180 --> 00:31:53,580 that it's going to take away from its health. 450 00:31:54,720 --> 00:32:01,860 Then we can check if this humanoid belongs to a zombie by seeing if the humanoid dot parent, which 451 00:32:01,860 --> 00:32:06,840 would be the character model, has that object value called who last damage. 452 00:32:06,840 --> 00:32:14,820 So if we find first child who last damaged, then that means this was a zombie we damaged and we can 453 00:32:14,820 --> 00:32:21,900 go ahead and update the humanoid dot parent dot who last damaged and get the value. 454 00:32:21,900 --> 00:32:26,340 And we're going to set that equal to the player that got passed to our function. 455 00:32:27,310 --> 00:32:35,830 Now we can go ahead and call our on touch function pass other part as well as the player that has this 456 00:32:35,830 --> 00:32:36,580 tool. 457 00:32:37,640 --> 00:32:43,760 And something important for us to do is that we need to get the connection returned from our connect 458 00:32:43,760 --> 00:32:46,310 function and store it in a variable. 459 00:32:46,340 --> 00:32:53,210 That way, when our animation is over, we disconnect that connection to our touch part. 460 00:32:53,210 --> 00:32:59,990 So that way we're not unnecessarily listening to when our tool is touched, when the player is not swinging 461 00:32:59,990 --> 00:33:01,220 their knife around. 462 00:33:01,250 --> 00:33:03,200 So I'm going to create a variable. 463 00:33:03,200 --> 00:33:05,480 I'll call it touch connection. 464 00:33:08,160 --> 00:33:12,930 And now we're going to delay a function from running, and we're going to delay it by the properties 465 00:33:12,930 --> 00:33:14,310 dot animation duration. 466 00:33:14,310 --> 00:33:21,030 So after their swinging animation is over we want to go ahead and disconnect our touch connection. 467 00:33:21,030 --> 00:33:23,880 So we'll get touch connection and then disconnect it. 468 00:33:23,880 --> 00:33:29,160 So that way we are no longer listening to our touch parts touch event. 469 00:33:29,160 --> 00:33:34,230 And that way every single time this event is being fired, we're not unnecessarily connecting multiple 470 00:33:34,230 --> 00:33:36,750 different functions to our same touch part. 471 00:33:37,370 --> 00:33:44,480 So now we can go ahead and play our game and see if we are able to damage this player or this example, 472 00:33:44,480 --> 00:33:46,760 a rig that is standing in our game. 473 00:33:46,760 --> 00:33:50,060 So if we go and swing our knife, there we go. 474 00:33:50,060 --> 00:33:52,550 We've damaged them and then perfect. 475 00:33:52,550 --> 00:33:59,060 So now we are able to damage this, uh, rig that was in our game here. 476 00:33:59,060 --> 00:34:02,120 I've placed multiple rigs down, and now if I go and attack them. 477 00:34:05,910 --> 00:34:12,240 Well, it does seem like that we are hitting them multiple times with our knife, which we don't want 478 00:34:12,240 --> 00:34:18,930 to happen, because if you heard the sound of our knife stab, it happened multiple times very quickly. 479 00:34:19,110 --> 00:34:25,410 And that's probably because this touched event is being fired multiple times, because our knife is 480 00:34:25,410 --> 00:34:27,510 going to be touching so many different limbs. 481 00:34:28,330 --> 00:34:33,010 And because we're touching it multiple different times, it's going to be damaging our humanoid multiple 482 00:34:33,010 --> 00:34:36,610 times, and it's going to be playing this hit sound multiple times. 483 00:34:36,850 --> 00:34:42,940 So that means we should probably add a D bounce for our on touched function. 484 00:34:42,940 --> 00:34:49,750 So that way we are not mistakenly damaging the humanoid many times in a second. 485 00:34:50,440 --> 00:34:53,350 So what we can go ahead and do is create another boolean up here. 486 00:34:53,350 --> 00:34:55,810 And I'm going to call this my touch Debounce. 487 00:34:55,810 --> 00:34:57,700 And we're going to set it equal to false. 488 00:34:58,370 --> 00:35:05,540 And then inside of our untouched function, we're going to check if touch debounce is true, and if 489 00:35:05,540 --> 00:35:07,100 it is, we're going to return. 490 00:35:07,100 --> 00:35:10,220 Otherwise we're going to set touch Debounce equal to true. 491 00:35:10,990 --> 00:35:17,620 And then to prevent us from damaging something more than once, we're going to set touch debounce to 492 00:35:17,620 --> 00:35:19,870 false down here instead. 493 00:35:19,900 --> 00:35:22,750 So touch debounce equal to false. 494 00:35:22,750 --> 00:35:29,950 That way we are guaranteed to only damage a zombie once every single time we swing our knife. 495 00:35:29,950 --> 00:35:32,170 So now if we go and playtest our game. 496 00:35:33,770 --> 00:35:38,330 And we grab our knife and we go to attack these rigs. 497 00:35:38,330 --> 00:35:46,130 If I go and swing it, as you can see, I only damaged once instead of many times in that one single 498 00:35:46,130 --> 00:35:47,150 swing of my knife. 499 00:35:47,150 --> 00:35:48,200 Let me try it again. 500 00:35:48,800 --> 00:35:49,430 There we go. 501 00:35:49,430 --> 00:35:50,720 Only damaged once. 502 00:35:52,040 --> 00:35:54,260 Let me see if I can try to get a critical hit. 503 00:35:55,730 --> 00:36:01,370 No critical hit, but as you can see now we're only damaging our rigs once per swing. 504 00:36:03,790 --> 00:36:10,510 So that's how we can create a melee weapon to damage any humanoid characters in our game. 505 00:36:10,930 --> 00:36:13,390 See you in the next lecture.